/*
Copyright 2024 - 2025 Zen HuiFer

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package router

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/influxdata/influxdb-client-go/v2/api"
	"igp/biz"
	"igp/glob"
	"igp/servlet"
	"igp/ut"
	"reflect"
)

type InfluxDbApi struct{}

var InfluxdbBiz = biz.InfluxdbBiz{}

// QueryInfluxdb
// @Tags      DATA
// @Summary   数据查询
// @accept    application/json
// @Produce   application/json
// @Param     data  body      servlet.InfluxQueryConfig true "查询参数"
// @Success   200  {object}  servlet.JSONResult
// @Router    /query/influxdb [post]
func (s *InfluxDbApi) QueryInfluxdb(c *gin.Context) {
	json := servlet.InfluxQueryConfig{}

	// fixme: 修订多协议的情况

	err := c.ShouldBind(&json)
	if err != nil {
		glob.GLog.Sugar().Error("操作异常", err)
		panic(err)

	}
	json.Bucket = ut.CalcBucketName(glob.GConfig.InfluxConfig.Bucket, json.Protocol,json.DeviceUid)
	query := json.GenerateFluxQuery()
	glob.GLog.Sugar().Info(query)
	result, err := glob.GInfluxdb.QueryAPI(glob.GConfig.InfluxConfig.Org).Query(context.Background(), query)
	if err != nil {
		panic(err)
	}
	defer func(result *api.QueryTableResult) {
		_ = result.Close()
	}(result)

	var v []map[string]interface{}

	for result.Next() {

		values := result.Record().Values()
		v = append(v, values)
	}
	field := groupByField(v)

	servlet.Resp(c, field)

}

// QueryMeasurement
// @Tags      DATA
// @Summary   查询Measurement明细
// @accept    application/json
// @Produce   application/json
// @Param     data  body      servlet.InfluxQueryConfig true "查询参数"
// @Success   200  {object}  servlet.JSONResult
// @Router    /query/QueryMeasurement [post]
func (s *InfluxDbApi) QueryMeasurement(c *gin.Context) {
	json := servlet.InfluxQueryConfig{}
	err := c.ShouldBind(&json)
	if err != nil {
		glob.GLog.Sugar().Error("操作异常", err)
		panic(err)

	}

	measurement := InfluxdbBiz.QueryMeasurement(json.Measurement, json.Protocol)
	servlet.Resp(c, measurement)
}

// QueryInfluxdbString
// @Tags      DATA
// @Summary   数据查询字符串
// @accept    application/json
// @Produce   application/json
// @Param     data  body      servlet.InfluxQueryConfig true "查询参数"
// @Success   200  {object}  servlet.JSONResult
// @Router    /query/str-influxdb [post]
func (s *InfluxDbApi) QueryInfluxdbString(c *gin.Context) {
	json := servlet.InfluxQueryConfig{}
	err := c.ShouldBind(&json)
	if err != nil {
		glob.GLog.Sugar().Error("操作异常", err)
		panic(err)

	}
	json.Bucket = ut.CalcBucketName(glob.GConfig.InfluxConfig.Bucket, json.Protocol,json.DeviceUid)

	query := json.GenerateFluxQueryString()
	glob.GLog.Sugar().Info(query)
	result, err := glob.GInfluxdb.QueryAPI(glob.GConfig.InfluxConfig.Org).Query(context.Background(), query)
	if err != nil {
		panic(err)
	}
	defer func(result *api.QueryTableResult) {
		_ = result.Close()
	}(result)

	var v []map[string]interface{}

	for result.Next() {

		values := result.Record().Values()
		v = append(v, values)
	}
	field := groupByField(v)

	servlet.Resp(c, field)

}

func groupByField(records []map[string]interface{}) map[string][]map[string]interface{} {
	grouped := make(map[string][]map[string]interface{})

	for _, record := range records {
		// 检查_field是否存在于记录中
		if fieldVal, ok := record["_field"]; ok {
			if fieldValStr, ok := fieldVal.(string); ok {
				// 使用_field的值作为分组的键
				grouped[fieldValStr] = append(grouped[fieldValStr], record)
			} else {
				fmt.Printf("Expected _field to be a string, got %s\n", reflect.TypeOf(fieldVal))
			}
		} else {
			fmt.Println("_field not found in record")
		}
	}

	return grouped
}
